;=================================================
;符号导入
;=================================================
extern screen_cursor
extern screen_width
extern screen_high
extern screen_size
;=================================================
;符号导出
;=================================================
global _Low_PrintStr
global _Low_PrintChar
global _Low_IntToStr
global _Low_ScreenClean
global _Low_MemCopy
global interrupt_lock
global interrupt_unlock
global _Low_InByte
global _Low_OutByte
;=================================================
;函数 _Low_InByte: I/O 写入一个字节
;-------------------------------------------------
_Low_InByte: 
    push edx
    mov edx, [esp + 4*2]
    xor eax, eax
    in al, dx
    pop edx
    nop
    ret
;=================================================
;函数 _Low_OutByte: I/O 写出入一个字节
;-------------------------------------------------
_Low_OutByte:
    push edx      
    mov edx, [esp + 4*2]
    mov al, [esp + 4*3]
    out dx, al
    pop edx
    nop
    ret
;=================================================
; 函数 : _Low_MemCopy  内存拷贝
;-------------------------------------------------
_Low_MemCopy:
    push edi
    push esi
    push ecx

    mov ecx, [esp + 4 * 6]
    mov esi, [esp + 4 * 5]
    mov edi, [esp + 4 * 4]
.COPY_LOOP:
    cmp ecx, 0
    je  .COPY_DONE
    lodsb
    mov byte [es:edi], al
    inc edi
    loop .COPY_LOOP

.COPY_DONE:
    pop ecx
    pop esi
    pop edi
    ret
;=================================================
; 函数 : _Low_PrintStr  打印字符串
;-------------------------------------------------
_Low_PrintStr:
    xor ecx, ecx
    mov esi, dword [esp + 4]
    mov edi, [screen_cursor]

CHAR_LOOP:
    mov ah, 0x07
    lodsb
    cmp al, 0x00
    je  CHAR_NUL
    cmp al, 0x0A
    je  CHAR_LF

    mov word [gs:edi], ax
    add edi, 2

    inc ecx
    jmp CHAR_LOOP

CHAR_LF:
    add edi, 0xA0

    xor edx, edx                                ;只需要eax中的除数
    mov eax, edi
    push eax                                    ;保存eax
    mov ebx, 0xA0                               ;行长  80 * 2 = 0xA0
    div ebx
    cmp eax, [screen_high]                      ;比较是否到了屏幕最后一行
    jae  FIRST_LINE

    pop eax                                     ;取出eax
    sub eax, edx                                ;减掉余数
    mov edi, eax
    inc ecx
    jmp CHAR_LOOP

FIRST_LINE:
    xor edi, edi
    pop eax
    inc ecx
    jmp CHAR_LOOP

CHAR_NUL:                                       ;0x9056c
    mov dword [screen_cursor], edi
    inc ecx
    mov eax, ecx                                ;返回值，字符个数

    ret
;=================================================
; 函数 : _Low_PrintChar  打印字符
;-------------------------------------------------
_Low_PrintChar:
    mov dx, word [esp + 4]
    mov edi, dword [screen_cursor]
    mov word [gs:edi], dx

    add edi, 2
    mov dword [screen_cursor], edi
    ret
;=================================================
; 函数 : _Low_IntToStr  打印数字
;-------------------------------------------------
_Low_IntToStr:
    mov ebx, 10
    mov ecx, 0
DIV_10_LOOP:
    cmp eax, 0
    je STACK_PRT

    xor edx, edx
    div ebx

    add dl, 0x30
    mov dh, 0xC
    push edx
    inc ecx
    jmp DIV_10_LOOP

STACK_PRT:
    cmp ecx, 0
    je STACK_PRT_DONE
    dec ecx
    call _Low_PrintChar
    add esp, 4
    jmp STACK_PRT
STACK_PRT_DONE:
    ret
;=================================================
; 函数 : _Low_ScreenClean  清屏
;-------------------------------------------------
_Low_ScreenClean:
    mov eax, [screen_high]
    mov ebx, [screen_width]
    mul ebx
    mov ebx, 2
    div ebx

    mov edi, 0
F_BYTE_LOOP:
    cmp eax, 0
    je CLEAN_DONE
    dec eax
    mov dword [gs:edi], 0
    add edi, 4
    jmp F_BYTE_LOOP
CLEAN_DONE:
    mov dword [screen_cursor], 0
    ret
;=================================================
; 函数 : interrupt_lock  屏蔽中断
;-------------------------------------------------
interrupt_lock:
    cli
    ret
;=================================================
; 函数 : interrupt_unlock  开启中断
;-------------------------------------------------
interrupt_unlock:
    sti
    ret

global clock_int
clock_int:
    int 32
    ret